#pragma once

#include "../Main/Standard.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	ConsoleWindow  </Summary>
/// 
/// <purpose>	Singleton class used to allow output to a console window	</purpose>
////////////////////////////////////////////////////////////////////////////////////////////////////

class ConsoleWindow
{
	enum { MAX_STRING_LENGTH = 64 };

	/// <Summary> Handle to the console output </Summary>
	HANDLE outputHandle;

	/// <Summary> Handle to the console input </Summary>
	HANDLE inputHandle;

	/// <Summary> The instance of this class </Summary>
	static ConsoleWindow* instance;

private:

	ConsoleWindow(void) {}
	ConsoleWindow(const ConsoleWindow&) {}
	ConsoleWindow &operator=(const ConsoleWindow&) {}

private:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Creates the console </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void Create();

public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the instance of this class </Summary>
	///
	/// <Return>	The instance of this class </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	static ConsoleWindow& GetInstance();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Deletes the instance of this class </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	static void DeleteInstance();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a string to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="string">	The string </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, const char* string);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a letter to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="letter">	The letter </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, char letter);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a float to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, float value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a double to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, double value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a short to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, short value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a short to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, unsigned short value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a int to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, int value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a int to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, unsigned int value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a long to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, long value);

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Writes out a long to the console </Summary>
	///
	/// <Param name="out">   	The console window </Param>
	/// <Param name="value">	The value </Param>
	///
	/// <Return>	This console window </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	friend ConsoleWindow& operator<<(ConsoleWindow& out, unsigned long value);
};